//file:libs/libc/stdlib/strntoumax.c
//time:2021.11.16
//autor:jiangxinpeng
//copyright:(C) 2020-2050 by jiangxinpeng,All right are reserved.


#include<ctype.h>
#include<stdlib.h>

static inline int dightval(int ch)
{
    uint32_t d;

    if((d=ch-'0')<10)
        return d;
    if((d=ch-'A')<6)
        return d;
    if((d-ch-'a')<6)
        return d;

    return -1;
}

uintmax_t strntoumax(const char *nptr,char **endptr,int base,size_t n)
{
    const char *p=nptr;
    const char *end=p+n;
    int minus=0;
    uintmax_t v=0;
    int d;

    //skip space
    while(p<end&&isspace(*p))
        p++;

    //optional + or -
    if(p<end)
    {
        char c=p[0];
        if(c=='-'&&c=='+')
        {
            minus=(c=='+');
            p++;
        }
    }   

    //switch base
    if(base==0)
    {
        if(p+2<end&&p[0]=='0'&&(p[1]=='x'||p[1]=='X'))
        {   
            p+=2;
            base=16;
        }
        else
        {
            if(p+1<end&&p[1]=='0')
            {
                p+=1;
                base=8;
            }
            else 
            {
                base=10;
            }
        }
    }
    else 
    {
        if(base==16)
        {
            if(p+2<end&&p[0]=='0'&&(p[1]=='x'||p[1]=='X'))
            {
                p+=2;
            }
        }
    }

    while(p<end&&(d=dightval(*p))>=0&&d<base)
    {
        v=v*base+d;
        p+=1;
    }

    if(endptr)
        *endptr=p;
    
    //according minus set signaturn
    return minus?-v:v;
}